﻿//  Copyright (c) 2010 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.UI;
using System.Xml;

namespace DNA.Mvc.jQuery
{

    public abstract class DataBindableComponentBuilder<TComponent, TNode, TFactory, TBuilder> : ViewComponentBuilder<TComponent, TBuilder>
        where TNode : NavigableView, IComponentItemContainer<TNode>
        where TComponent : DataBindableComponentContainer<TNode>
        where TBuilder : DataBindableComponentBuilder<TComponent, TNode, TFactory, TBuilder>
    {
        public DataBindableComponentBuilder(TComponent component, ViewContext context, IViewDataContainer container) : base(component, context, container) { }

        protected abstract TFactory CreateNodeItemFactory();

        protected abstract HierarchialBindingFactory<TNode, TComponent> CreateBindingFactory();

        public TBuilder Items(Action<TFactory> items)
        {
            if (items != null)
                items.Invoke(CreateNodeItemFactory());
            return this as TBuilder;
        }

        public TBuilder ItemDataBound(Action<TNode> item)
        {
            Component.ItemDataBoundTemplate = item;
            return this as TBuilder;
        }

        private HierarchialBindingFactory<TNode, TComponent> Factory
        {
            get
            {
                return CreateBindingFactory();
            }
        }

        public TBuilder Bind<T>(IHierarchicalEnumerable model, MapAction<T, NavigatableNode> mapper)
        {
            Factory.Bind<T>(model, mapper);
            return this as TBuilder;
        }

        public TBuilder Bind(IHierarchicalNodeProvider dataProvider)
        {
            return this.Bind(dataProvider, true);
        }

        public TBuilder Bind(IHierarchicalNodeProvider dataProvider,bool showRoot)
            //where T : HierarchicalNode
        {
            Factory.Bind(dataProvider,showRoot);
            return this as TBuilder;
        }

        public TBuilder Bind<T>(T root)
     where T : HierarchicalNode
        {
            return this.Bind<T>(root, true);
        }

        public TBuilder Bind<T>(T root,bool showRoot)
             where T : HierarchicalNode
        {
            Factory.Bind<T>(root, null,showRoot);
            return this as TBuilder;
        }

        public TBuilder Bind<T>(T root, Func<T, bool> dataBound)
                 where T : HierarchicalNode
        {
            return this.Bind<T>(root, dataBound, true);
        }

        public TBuilder Bind<T>(T root, Func<T, bool> dataBound,bool showRoot)
             where T : HierarchicalNode
        {
            Factory.Bind<T>(root, dataBound,showRoot);
            return this as TBuilder;
        }

        public virtual TBuilder Bind(string xmlUrl)
        {
            return this.Bind(xmlUrl, true);
        }

        public virtual TBuilder Bind(string xmlUrl,bool showRoot)
        {
            Factory.BindXml(xmlUrl,showRoot);
            return this as TBuilder;
        }

        public TBuilder Bind(string xmlUrl, MapAction<XmlNode, HierarchicalNode> mapper)
        {
            return this.Bind(xmlUrl, mapper, true);
        }

        public TBuilder Bind(string xmlUrl, MapAction<XmlNode, HierarchicalNode> mapper,bool showRoot)
        {
            Factory.BindXml(xmlUrl, mapper,showRoot);
            return this as TBuilder;
        }

        public TBuilder BindSiteMap(string siteMapUrl)
        {
            Factory.BindSiteMap(siteMapUrl);
            return this as TBuilder;
        }

        public TBuilder BindSiteMap(string siteMapUrl, string selectPath)
        {
            Factory.BindSiteMap(siteMapUrl, selectPath);
            return this as TBuilder;
        }
    }
}
